package com.todo.gateway.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.cors.reactive.CorsWebFilter;

import javax.annotation.Resource;

/**
 * @author azhebuxing
 * @date 2025/2/21 21:32
 * @description see:https://blog.csdn.net/jilo88/article/details/120026353
 */
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {


    @Resource
    private CorsWebFilter corsFilter;
    @Resource
    private JwtAuthenticationFilter jwtAuthenticationFilter;
    @Resource
    private InjectBodyInfoFilter injectBodyInfoFilter;
//    @Resource
//    private LoggerFilter loggerFilter;

    @Bean
    public SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity httpSecurity) {

        httpSecurity
                .csrf().disable()// 禁用 CSRF 保护
                .authorizeExchange()
                .pathMatchers("/web/**", "/m/**", "/app/**").permitAll()
                .pathMatchers("/public/**").permitAll()
                //其他接口
                .anyExchange().authenticated()
                .and()
                // 添加JWT filter   需要一开始就通过token识别出登录用户 并放到上下文中   所以jwtFilter需要放前面
                // 添加 CORS 过滤器
                .addFilterAt(jwtAuthenticationFilter, SecurityWebFiltersOrder.AUTHENTICATION)// 在 AUTHENTICATION 位置添加过滤器
                .addFilterBefore(corsFilter, SecurityWebFiltersOrder.CORS)
                .addFilterBefore(injectBodyInfoFilter, SecurityWebFiltersOrder.AUTHENTICATION)
                //.addFilterBefore(loggerFilter, SecurityWebFiltersOrder.AUTHENTICATION)
                // 禁用 X-Frame-Options 响应头。下面是具体解释：
                // X-Frame-Options 是一个 HTTP 响应头，用于防止网页被嵌入到其他网页的 <frame>、<iframe> 或 <object> 标签中，从而可以减少点击劫持攻击的风险
                .headers().frameOptions().disable();

        return httpSecurity.build();
    }


}
